package com.lifeverse.entity;

import com.lifeverse.entity.enums.UserStatus;
import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户实体
 * 实现Spring Security的UserDetails接口
 */
@Entity
@Table(name = "users", indexes = {
    @Index(name = "idx_user_username", columnList = "username", unique = true),
    @Index(name = "idx_user_email", columnList = "email", unique = true),
    @Index(name = "idx_user_status", columnList = "status"),
    @Index(name = "idx_user_last_login", columnList = "last_login_at")
})
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User extends BaseEntity implements UserDetails {
    
    /**
     * 用户名
     */
    @Column(name = "username", nullable = false, unique = true, length = 50)
    private String username;
    
    /**
     * 密码（加密后）
     */
    @Column(name = "password", nullable = false, length = 100)
    private String password;
    
    /**
     * 邮箱
     */
    @Column(name = "email", nullable = false, unique = true, length = 100)
    private String email;
    
    /**
     * 真实姓名
     */
    @Column(name = "real_name", length = 50)
    private String realName;
    
    /**
     * 手机号
     */
    @Column(name = "phone", length = 20)
    private String phone;
    
    /**
     * 头像URL
     */
    @Column(name = "avatar_url", length = 500)
    private String avatarUrl;
    
    /**
     * 用户状态
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 20)
    private UserStatus status;
    
    /**
     * 是否启用
     */
    @Column(name = "enabled", nullable = false)
    private Boolean enabled;
    
    /**
     * 账户是否未过期
     */
    @Column(name = "account_non_expired", nullable = false)
    private Boolean accountNonExpired;
    
    /**
     * 账户是否未锁定
     */
    @Column(name = "account_non_locked", nullable = false)
    private Boolean accountNonLocked;
    
    /**
     * 凭证是否未过期
     */
    @Column(name = "credentials_non_expired", nullable = false)
    private Boolean credentialsNonExpired;
    
    /**
     * 最后登录时间
     */
    @Column(name = "last_login_at")
    private LocalDateTime lastLoginAt;
    
    /**
     * 最后登录IP
     */
    @Column(name = "last_login_ip", length = 45)
    private String lastLoginIp;
    
    /**
     * 登录失败次数
     */
    @Column(name = "failed_login_attempts")
    private Integer failedLoginAttempts;
    
    /**
     * 账户锁定时间
     */
    @Column(name = "locked_at")
    private LocalDateTime lockedAt;
    
    /**
     * 密码过期时间
     */
    @Column(name = "password_expires_at")
    private LocalDateTime passwordExpiresAt;
    
    /**
     * 用户角色
     */
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(
        name = "user_roles",
        joinColumns = @JoinColumn(name = "user_id"),
        inverseJoinColumns = @JoinColumn(name = "role_id")
    )
    private Set<Role> roles;
    
    /**
     * 用户配置（JSON格式）
     */
    @Column(name = "user_config", columnDefinition = "TEXT")
    private String userConfig;
    
    /**
     * 用户偏好设置（JSON格式）
     */
    @Column(name = "preferences", columnDefinition = "TEXT")
    private String preferences;
    
    /**
     * 部门ID
     */
    @Column(name = "department_id")
    private Long departmentId;
    
    /**
     * 职位
     */
    @Column(name = "position", length = 100)
    private String position;
    
    /**
     * 备注
     */
    @Column(name = "description", length = 500)
    private String description;
    
    // Spring Security UserDetails 接口实现
    
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return roles.stream()
                .flatMap(role -> role.getPermissions().stream())
                .map(permission -> new SimpleGrantedAuthority(permission.getPermissionCode()))
                .collect(Collectors.toSet());
    }
    
    @Override
    public String getPassword() {
        return password;
    }
    
    @Override
    public String getUsername() {
        return username;
    }
    
    @Override
    public boolean isAccountNonExpired() {
        return accountNonExpired != null ? accountNonExpired : true;
    }
    
    @Override
    public boolean isAccountNonLocked() {
        return accountNonLocked != null ? accountNonLocked : true;
    }
    
    @Override
    public boolean isCredentialsNonExpired() {
        if (credentialsNonExpired != null && !credentialsNonExpired) {
            return false;
        }
        if (passwordExpiresAt != null) {
            return LocalDateTime.now().isBefore(passwordExpiresAt);
        }
        return true;
    }
    
    @Override
    public boolean isEnabled() {
        return enabled != null ? enabled : false;
    }
    
    /**
     * 检查用户是否有指定权限
     */
    public boolean hasPermission(String permissionCode) {
        return getAuthorities().stream()
                .anyMatch(authority -> authority.getAuthority().equals(permissionCode));
    }
    
    /**
     * 检查用户是否有指定角色
     */
    public boolean hasRole(String roleCode) {
        return roles.stream()
                .anyMatch(role -> role.getRoleCode().equals(roleCode));
    }
    
    /**
     * 增加登录失败次数
     */
    public void incrementFailedLoginAttempts() {
        this.failedLoginAttempts = (this.failedLoginAttempts != null ? this.failedLoginAttempts : 0) + 1;
    }
    
    /**
     * 重置登录失败次数
     */
    public void resetFailedLoginAttempts() {
        this.failedLoginAttempts = 0;
    }
    
    /**
     * 锁定账户
     */
    public void lockAccount() {
        this.accountNonLocked = false;
        this.lockedAt = LocalDateTime.now();
        this.status = UserStatus.LOCKED;
    }
    
    /**
     * 解锁账户
     */
    public void unlockAccount() {
        this.accountNonLocked = true;
        this.lockedAt = null;
        this.failedLoginAttempts = 0;
        this.status = UserStatus.ACTIVE;
    }
    
    /**
     * 更新最后登录信息
     */
    public void updateLastLogin(String ipAddress) {
        this.lastLoginAt = LocalDateTime.now();
        this.lastLoginIp = ipAddress;
        this.resetFailedLoginAttempts();
    }
    
    /**
     * 检查账户是否需要锁定
     */
    public boolean shouldLockAccount(int maxFailedAttempts) {
        return this.failedLoginAttempts != null && this.failedLoginAttempts >= maxFailedAttempts;
    }
    
    /**
     * 创建用户的静态方法
     */
    public static User create(String username, String password, String email, String realName) {
        return User.builder()
                .username(username)
                .password(password)
                .email(email)
                .realName(realName)
                .status(UserStatus.ACTIVE)
                .enabled(true)
                .accountNonExpired(true)
                .accountNonLocked(true)
                .credentialsNonExpired(true)
                .failedLoginAttempts(0)
                .build();
    }
}